package com.example.demo.web.filter;

import cn.hutool.http.ContentType;
import com.alibaba.fastjson2.JSON;
import com.example.demo.domain.base.BaseResult;
import com.example.demo.exception.BizException;
import com.example.demo.util.ProfileUtil;
import com.example.demo.util.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;

/**
 * Sign 过滤器
 *
 * @author wangchen
 * @date 2025/7/17 17:13
 **/
@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 20)
public class SignGenerateFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (ProfileUtil.isDev() || ProfileUtil.isSignExcluded(request.getRequestURI())) {
            filterChain.doFilter(request, response);
            return;
        }

        // 验证签名
        try {
            SignUtil.verifySign(request);
            // 验证通过：继续处理请求
            filterChain.doFilter(request, response);
        } catch (BizException e) {
            // 手动设置响应
            response.setStatus(400);
            response.setContentType(ContentType.JSON.toString(Charset.defaultCharset()));
            // 使用try-with-resources自动关闭Writer，确保响应发送
            try (PrintWriter writer = response.getWriter()) {
                String errorJson = JSON.toJSONString(BaseResult.failure(e.getCode(), e.getMessage()));
                writer.write(errorJson);
                writer.flush(); // 强制刷新缓冲区
            } catch (IOException ex) {
                log.error("写入错误响应失败", ex);
            }
        }
    }
}
